{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8419a7f3-4ec0-4374-9979-557bd27cbc2d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.stats"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41063b1b-24c6-40a1-ab1d-9044b50a817e",
   "metadata": {},
   "source": [
    "# 实用的功能\n",
    "\n",
    "方法|描述\n",
    "--:|:--\n",
    "apply_along_axis(func1d, axis, arr, *args, …)|沿给定轴将函数应用于一维切片。\n",
    "apply_over_axes(func, a, axes)|在多个轴上重复应用函数。\n",
    "vectorize(pyfunc[, otypes, doc, excluded, …])|广义函数类。\n",
    "frompyfunc(func, nin, nout)|接受任意Python函数并返回NumPy ufunc。\n",
    "piecewise(x, condlist, funclist, *args, **kw)|评估分段定义的函数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6029e678-daa3-484f-ab02-91d24ed5c64d",
   "metadata": {},
   "source": [
    "## numpy.apply_along_axis(func1d, axis, arr, *args, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b722dd1d-f1d0-47d4-9c0d-f15eb127fa63",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4., 5., 6.])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def my_func(a):\n",
    "    \"\"\"Average first and last element of a 1-D array\"\"\"\n",
    "    return (a[0] + a[-1]) * 0.5\n",
    "b = np.array([[1,2,3], [4,5,6], [7,8,9]])\n",
    "np.apply_along_axis(my_func, 0, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cd8afc3f-c2e6-4387-88e1-fe01d242f8f0",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2., 5., 8.])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.apply_along_axis(my_func, 1, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "01c2ffa8-25b1-4ac8-a285-3efab5591e59",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 7, 8],\n",
       "       [3, 4, 9],\n",
       "       [2, 5, 6]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = np.array([[8,1,7], [4,3,9], [5,2,6]])\n",
    "np.apply_along_axis(sorted, 1, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a8027221-5520-4f1b-9a9f-bec9d12893bf",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[1, 0, 0],\n",
       "        [0, 2, 0],\n",
       "        [0, 0, 3]],\n",
       "\n",
       "       [[4, 0, 0],\n",
       "        [0, 5, 0],\n",
       "        [0, 0, 6]],\n",
       "\n",
       "       [[7, 0, 0],\n",
       "        [0, 8, 0],\n",
       "        [0, 0, 9]]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = np.array([[1,2,3], [4,5,6], [7,8,9]])\n",
    "np.apply_along_axis(np.diag, -1, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7551344-becd-4567-bf16-314d7cb09ce3",
   "metadata": {},
   "source": [
    "## numpy.apply_over_axes(func, a, axes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b750ce4f-b51b-4f43-913c-4a5b0171f7ca",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]],\n",
       "\n",
       "       [[12, 13, 14, 15],\n",
       "        [16, 17, 18, 19],\n",
       "        [20, 21, 22, 23]]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.arange(24).reshape(2,3,4)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "81dafc77-dcd0-4cf4-9228-50d81f501a67",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 60],\n",
       "        [ 92],\n",
       "        [124]]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.apply_over_axes(np.sum, a, [0,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a09dd34a-fd97-4ec3-9f17-9d99d0c64eb4",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 60],\n",
       "        [ 92],\n",
       "        [124]]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(a, axis=(0,2), keepdims=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ae71a79-a8d7-4e13-ac43-6fb7e93e1ccd",
   "metadata": {},
   "source": [
    "## class numpy.vectorize(pyfunc=np._NoValue, otypes=None, doc=None, excluded=None, cache=False, signature=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "43097dcb-5a77-42ba-a9fa-a4940d2cef42",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def myfunc(a, b):\n",
    "    \"Return a-b if a>b, otherwise return a+b\"\n",
    "    if a > b:\n",
    "        return a - b\n",
    "    else:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3b2257dc-4742-4bb0-b652-70ec0ce6a377",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 4, 1, 2])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vfunc = np.vectorize(myfunc)\n",
    "vfunc([1, 2, 3, 4], 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "691587fb-8a70-441f-afc9-82a1f374e61a",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Return a-b if a>b, otherwise return a+b'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vfunc.__doc__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9b47a877-b7d5-443c-9341-c81fae86fd74",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Vectorized `myfunc`'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')\n",
    "vfunc.__doc__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7cee4f19-f8a9-4c68-b425-65ccda9b9597",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.int64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "out = vfunc([1, 2, 3, 4], 2)\n",
    "type(out[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "03a87cc2-d79f-418a-97f0-7348a7628366",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.float64"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vfunc = np.vectorize(myfunc, otypes=[float])\n",
    "out = vfunc([1, 2, 3, 4], 2)\n",
    "type(out[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "218813f9-9b7c-4c8b-8061-7fadff40f0cb",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def mypolyval(p, x):\n",
    "    _p = list(p)\n",
    "    res = _p.pop(0)\n",
    "    while _p:\n",
    "        res = res*x + _p.pop(0)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "b0b22059-b833-4d4a-9f7c-6c7ec7b93388",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 6])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vpolyval = np.vectorize(mypolyval, excluded=['p'])\n",
    "vpolyval(p=[1, 2, 3], x=[0, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8f457702-2cd3-4479-9985-be363b8d71a5",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 6])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vpolyval.excluded.add(0)\n",
    "vpolyval([1, 2, 3], x=[0, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f372e917-646a-46ec-a0e6-c175cfef44dd",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 1., -1.]), array([0., 0.]))"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pearsonr = np.vectorize(scipy.stats.pearsonr,\n",
    "                signature='(n),(n)->(),()')\n",
    "pearsonr([[0, 1, 2, 3]], [[1, 2, 3, 4], [4, 3, 2, 1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9dbbefea-fe58-41dc-a8b7-3689f6333939",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 2., 1., 0., 0., 0.],\n",
       "       [0., 1., 2., 1., 0., 0.],\n",
       "       [0., 0., 1., 2., 1., 0.],\n",
       "       [0., 0., 0., 1., 2., 1.]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "convolve = np.vectorize(np.convolve, signature='(n),(m)->(k)')\n",
    "convolve(np.eye(4), [1, 2, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "21f8ff32-08d8-490e-a0d7-958624b1b987",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@np.vectorize\n",
    "def identity(x):\n",
    "    return x\n",
    "\n",
    "identity([0, 1, 2])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e25bf35-a1dd-4c8f-b82d-971c2eba8951",
   "metadata": {},
   "source": [
    "## numpy.frompyfunc(func, /, nin, nout, *[, identity])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "bc1e17de-fd5e-42bf-888e-5a2e56b8f7e7",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['0o12', '0o36', '0o144'], dtype=object)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "oct_array = np.frompyfunc(oct, 1, 1)\n",
    "oct_array(np.array((10, 30, 100)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3138459c-d838-4631-9b8e-70e6ef84f573",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['0o12', '0o36', '0o144'], dtype='<U5')"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array((oct(10), oct(30), oct(100)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f59c0557-96b6-482a-b3bc-5fa284097067",
   "metadata": {},
   "source": [
    "## numpy.piecewise(x, condlist, funclist, *args, **kw)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "e44d4436-9185-4937-a7bd-ea7aef0b96f5",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1., -1., -1.,  1.,  1.,  1.])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.linspace(-2.5, 2.5, 6)\n",
    "np.piecewise(x, [x < 0, x >= 0], [-1, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "1fa1dcaf-8d1d-4eee-ae0d-804f59a84938",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.5, 1.5, 0.5, 0.5, 1.5, 2.5])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "116c01b8-8810-4eba-84fe-db0fd87b173e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(2)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = -2\n",
    "np.piecewise(y, [y < 0, y >= 0], [lambda x: -x, lambda x: x])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
